﻿using Mono.Cecil.PE;
using System;
using System.IO;
using System.IO.Compression;

namespace Mono.Cecil.Cil
{
    public sealed class EmbeddedPortablePdbReaderProvider : ISymbolReaderProvider
    {
        public ISymbolReader GetSymbolReader(ModuleDefinition module, string fileName)
        {
            Mixin.CheckModule(module);
            ImageDebugHeader debugHeader = module.GetDebugHeader();
            ImageDebugHeaderEntry embeddedPortablePdbEntry = debugHeader.GetEmbeddedPortablePdbEntry();
            if (embeddedPortablePdbEntry == null)
            {
                throw new InvalidOperationException();
            }

            return new EmbeddedPortablePdbReader((PortablePdbReader)new PortablePdbReaderProvider().GetSymbolReader(module, GetPortablePdbStream(embeddedPortablePdbEntry)));
        }

        private static Stream GetPortablePdbStream(ImageDebugHeaderEntry entry)
        {
            MemoryStream stream = new MemoryStream(entry.Data);
            BinaryStreamReader binaryStreamReader = new BinaryStreamReader(stream);
            binaryStreamReader.ReadInt32();
            int capacity = binaryStreamReader.ReadInt32();
            MemoryStream memoryStream = new MemoryStream(capacity);
            using (DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress, leaveOpen: true))
            {
                deflateStream.CopyTo(memoryStream);
            }

            return memoryStream;
        }

        public ISymbolReader GetSymbolReader(ModuleDefinition module, Stream symbolStream)
        {
            throw new NotSupportedException();
        }
    }
}